//
//  Block.m
//  HigherOrderMessaging
//
//  Created by Ofri Wolfus on 14/12/06.
//  Copyright 2006 Ofri Wolfus. All rights reserved.
//

#import "Block.h"


#define _DP_BLOCK_JMP_VALUE		888
#define _DP_RETURN_JMP_VALUE	777

struct dp_block_data {
	jmp_buf	_block_stack;
	//jmp_buf _caller_stack;
	BOOL	_initialized;
	CFMutableDictionaryRef info;
};

Block block_init(Block b) {
	b->info = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
										&kCFTypeDictionaryKeyCallBacks,
										NULL);
	[(NSDictionary *)(b->info) autorelease];
	b->_initialized = NO;
	return b;
}

Block block_create() {
	Block b = calloc(1, sizeof(struct dp_block_data));
	b->info = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
										&kCFTypeDictionaryKeyCallBacks,
										NULL);
	b->_initialized = NO;
	return b;
}

size_t block_get_size() {
	return sizeof(struct dp_block_data);
}

void block_free(Block b) {
	CFRelease(b->info);
	free(b);
}

void block_set_value_for_key(Block b, void *val, id key) {
	CFDictionarySetValue(b->info, key, val);
}

void * block_get_value_for_key(Block b, id key) {
	return (void *)CFDictionaryGetValue(b->info, key);
}

void block_process(Block b) {
	b->_initialized = YES;
	//if (!setjmp(b->_caller_stack))
	longjmp(b->_block_stack, 888);
}

BOOL block_is_initialized(Block b) {
	return b->_initialized;
}

/*#define DPBlock(statements...) \
({ \
	Block __block = block_create(); \
		if (setjmp(*((jmp_buf*)__block))) { \
			id	each = (id)block_get_value_for_key(__block, @"each"); \
__block_begin: \
				statements; \
					if (setjmp(*((jmp_buf*)__block)) == 888) { \
						each = (id)block_get_value_for_key(__block, @"each"); \
							goto __block_begin; \
					} else { \
						longjmp(*(((jmp_buf*)__block) + 1), 777); \
					} \
		} \
		__block; \
})*/
